Imports System.Drawing

Namespace Overlay
    ''' <summary>
    ''' The jChart.Overlay.StackedBarOverlay object is used to chart stacked area charts.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class StackedBarOverlay
        Inherits OverLayBase

        Private miBarColumnFillPercentage As Single = 0.7

        ''' <summary>
        ''' oChartDimensions is a jChart.ChartDimensions object that describes the interior of the chart. 
        ''' oXAxis and oYAxis are the X and Y axes that should be used for series belonging to the OverLay object.
        ''' </summary>
        ''' <param name="oChartDimensions"></param>
        ''' <param name="oXAxis"></param>
        ''' <param name="oYAxis"></param>
        ''' <remarks></remarks>
        Public Sub New( _
            ByVal oChartDimensions As ChartDimensions, _
            ByVal oXAxis As XAxis, _
            ByVal oYAxis As YAxis)

            MyBase.New(oChartDimensions, oXAxis, oYAxis)
        End Sub

        Protected Overrides Sub DrawAllSeries(ByRef g As Graphics)
            Dim oSeries As Series.StackedBarSeries = Nothing
            Dim iSeriesCount As Integer = moSeries.Count
            Dim oBaseValues(moXAxis.XAxisValues.GetUpperBound(0)) As Single

            For iValue As Integer = 0 To moXAxis.XAxisValues.GetUpperBound(0)
                oBaseValues(iValue) = moYAxis.YAxisValues(0)
            Next

            For iCurSeries As Integer = 0 To iSeriesCount - 1
                oSeries = moSeries(iCurSeries)
                SeriesToStackedBar(g, oSeries, iCurSeries, oBaseValues)
            Next
        End Sub

        Private Sub SeriesToStackedBar( _
                            ByRef g As Graphics, _
                            ByVal oSeries As Series.StackedBarSeries, _
                            ByVal iCurrentSeries As Integer, _
                            ByRef oBaseValues() As Single)

            '---Define area values.
            Dim iXPointCount As Integer = moXAxis.XAxisValues.GetUpperBound(0)

            Dim oTopValues(iXPointCount) As Single
            Dim oBottomValues(iXPointCount) As Single

            If oSeries.Values.GetUpperBound(0) < iXPointCount Then
                Throw New Exception("Not enough values for series: " & oSeries.Name)
            End If

            For iAreaPoint As Integer = 0 To iXPointCount
                '---Bottom of area is top of previous area
                oBottomValues(iAreaPoint) = oBaseValues(iAreaPoint)

                '---Now fill in current area
                oTopValues(iAreaPoint) = oSeries.Values(iAreaPoint) + oBaseValues(iAreaPoint)

                '---And remember total value for next series
                oBaseValues(iAreaPoint) = oSeries.Values(iAreaPoint) + oBaseValues(iAreaPoint)
            Next

            Dim oRegionList As ArrayList = Nothing
            oRegionList = CalculateBarAreaRegions(g, oSeries.Name, oTopValues, oBottomValues, moXAxis.XAxisLabelBoxWidth * miBarColumnFillPercentage, 0)
            For Each oRegion As RegionArea In oRegionList
                MyBase.AddPolygonRegion(oRegion)

                Dim oSemiTransparentColor As Color = Color.FromArgb(oSeries.AlphaValue, oSeries.Color.R, oSeries.Color.G, oSeries.Color.B)
                g.FillRegion(New SolidBrush(oSemiTransparentColor), oRegion.SeriesRegion)
            Next
        End Sub

        ''' <summary>
        ''' A value between 0 and 1 that represents the percentage of each column that should be filled by the bar. 
        ''' Use this property to control the amount of gap space between bars in a chart.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property BarColumnFillPercentage() As Single
            Get
                Return miBarColumnFillPercentage
            End Get
            Set(ByVal value As Single)
                miBarColumnFillPercentage = value
            End Set
        End Property
    End Class
End Namespace